#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#include"../../1027/linkstack/linkstack.h"//导入栈
#include"../../1027/linkqueue/queue.h"//导入队列

int get_priority(char op);//运算符优先级

int is_digital(char c);
int is_op(char c);
char *converse_last(char *p);
int my_cmputer(int num1, int num2, char c);
int compute(char *p);

int main(int argc, char *argv[])
{
    if (argc < 2)
        return 1;
	char *str = NULL;
	int ans;
	printf("后缀表达式：");
	str = converse_last(argv[1]);
	puts(str);

	ans = compute(str);
	printf("%d\n", ans);



	free(str);
	str = NULL;
    return 0;
}

int is_digital(char c){
	return '0' <= c && c <= '9';
}

int is_op(char c){
	return c == '+' || c == '-' || c == '*' || c == '/';
}

char *converse_last(char *p){
	char *str = malloc(strlen(p)+1);

	printf("开始生成后缀表达式\n");

	stack_t *opstack = NULL;    // 运算符栈
    queue_t *result = NULL;     // 结果队列
    int i;// 控制大循环
    char temp;

    stack_init(&opstack, sizeof(char));//初始化运算符栈
    queue_init(&result, sizeof(char));//初始化结果队列

	for(i = 0; i < strlen(p); i++){
		if(is_digital(p[i])){
			printf("第%d个是数字\n", i);
			enqueue(result, p + i);
		}
		else if(p[i] == '('){
			printf("第%d个是(\n", i);
			stack_push(opstack, p + i);
		}
		else if(p[i] == ')'){
			do{
				if(stack_empty(opstack)){
					printf("出错！！！\n");
				   	stack_destroy(&opstack);
    				queue_destroy(&result);
					free(str);
					str = NULL;
					return NULL;
				}
				stack_pop(opstack, &temp);
				if(temp != '(')
					enqueue(result, &temp);
			}while(temp != '(');
			//判断一下有无空
		}else if(is_op(p[i])){
			printf("操作！\n");
			while(1){
				if(stack_empty(opstack)){
					stack_push(opstack, p + i);
					break;
				}else{
					stack_pop(opstack, &temp);
					if(get_priority(temp) >= get_priority(p[i])){
						enqueue(result, &temp);
					}else{
						stack_push(opstack, &temp);
						stack_push(opstack, p + i);
						break;
					}
				}
			}
		}else{
		   	stack_destroy(&opstack);
    		queue_destroy(&result);
			free(str);
			str = NULL;
			return NULL;
		}	
	}

	while(!stack_empty(opstack)){
		stack_pop(opstack, &temp);
		enqueue(result, &temp);
	}


	int now = 0;
	while(!queue_is_empty(result)){
		dequeue(result, str + now);
		now++;
	}
	str[now] = '\0';

    stack_destroy(&opstack);
    queue_destroy(&result);

	return str;
	
}

int get_priority(char op){
	int res = 0;
	if(op == '+' || op == '-')
		res = 1;
	if(op == '*' || op == '/')
		res = 2;

	return res;
} 

int my_cmputer(int num1, int num2, char c){
	int ans = 0;
	switch(c){
		case '+':
			ans = num1 + num2;
			break;
		case '-':
			ans = num1 - num2;
			break;
		case '*':
			ans = num1 * num2;
			break;
		case '/':
			ans = num1 / num2;
			break;
		default:
			printf("算错了，下面不要看！！！\n");
			break;
	}
	return ans;
}

int compute(char *p){
	stack_t * ansstack = NULL;
	stack_init(&ansstack, sizeof(int));
	int num;
	int num1;
	int num2;
	int i = 0; 
	while(p[i] != '\0'){
		if(is_digital(p[i])){
			num = (int)(p[i] - '0');
			stack_push(ansstack, &num);
		}else if(is_op(p[i])){
			printf("计算\n");
			stack_pop(ansstack, &num2);
			stack_pop(ansstack, &num1);
			num = my_cmputer(num1,num2,p[i]);
			stack_push(ansstack, &num);
			//printf("num:%d\n", num);
		}
		i++;
	}

	stack_pop(ansstack, &num);
	stack_destroy(&ansstack);
	return num;
}
